/*
 * This file is part of Ember.
 *
 * Ember is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Ember is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Ember.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright (C) Grant Tyra 2010
 * granttyra@gmail.com
*/

#include "ember_object.h"
#include "ember_list.h"
#include "ember_types.h"
#include <stdlib.h>
#include <string.h>

void EmberObjectRetain(EmberObject *obj) {
    obj->refCount++;
}

void EmberObjectRelease(EmberObject *obj) {
    obj->refCount--;

    if (obj->refCount < 0) {
		EmberObjectDestroy(obj);
    }
}

void *EmberObjectGetAttribute(EmberObject *obj, const char *name) {
	return EmberDictionaryGet(obj->attributes, name);
}

void EmberObjectPutAttribute(EmberObject *obj, const char *name, void *attrib) {
	EmberDictionaryPut(obj->attributes, name, attrib);
}

EmberObject *EmberObjectCreate(const char *class_name) {
	EmberObject *obj = NULL;
    EmberClassDef *classdef = EmberClassMapGet(class_name);
    
    if (classdef == NULL) {
        return NULL;
    }
    
    obj = malloc(sizeof(EmberObject));
    obj->refCount = 0;
    obj->attributes = EmberDictionaryCreate();
    obj->classdef = classdef;
	obj->typeFlags = 0;
    return obj;
}

EmberObject *EmberObjectCreateException(const char *message) {
	EmberObject *exception = EmberObjectCreateString(message);
	exception->typeFlags = TYPE_EXCEPTION;
	return exception;
}

void EmberObjectDestroy(EmberObject *obj) {
	int i = 0;
    EmberList *attribs = NULL;
	EmberObject *attribute = NULL;

	if (obj == NULL) {
		return;
	}

	if ((obj->typeFlags & TYPE_INTEGER) || (obj->typeFlags & TYPE_DECIMAL) || (obj->typeFlags & TYPE_STRING)) {
		attribute = EmberObjectGetAttribute(obj, "value");
		free(attribute);
	} else if (obj->typeFlags & TYPE_LIST) {
		EmberListDestroy(EmberObjectGetAttribute(obj, "list"));
	} else if (obj->typeFlags & TYPE_DICT) {
		EmberDictionaryDestroy(EmberObjectGetAttribute(obj, "dict"));
	} else {
        attribs = EmberListCreate();
		EmberDictionaryValues(obj->attributes, attribs);

		for (i = 0; i < attribs->size; i++) {
			attribute = EmberListGet(attribs, i);
			EmberObjectRelease(attribute);
		}

		EmberListDestroy(attribs);
	}

	EmberDictionaryDestroy(obj->attributes);
	free(obj);
}
